import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
import { SaveMenuDto } from './dto/save-menu.dto';
import { PrismaService } from 'src/prisma/prisma.service';
import { Prisma, Menu } from '@prisma/client';
import { cloneDeep } from 'lodash-es';
import { buildTree, TreeItem } from 'src/utils/common';

@Injectable()
export class MenuService {
  @Inject(PrismaService) private prismaService: PrismaService;
  async save_menu(saveMenu: SaveMenuDto) {
    const { id } = saveMenu;
    if (id) {
      await this.prismaService.menu.update({
        where: {
          id,
        },
        data: saveMenu,
      });
      return {
        message: '菜单更新成功',
        messageType: 'success',
      };
    } else {
      delete saveMenu.id;
      await this.prismaService.menu.create({
        data: saveMenu,
      });
      return {
        message: '菜单创建成功',
        messageType: 'success',
      };
    }
  }

  async get_menu_list(
    page: number,
    size: number,
    filter: string,
    filterFields: string,
    dev: boolean = false,
  ) {
    const filterFieldsArr = filterFields
      ? filterFields.split(',').map((ele) => {
          return {
            [ele]: { contains: filter },
          };
        })
      : [];
    const where = filter ? { OR: filterFieldsArr } : {};
    const total = await this.prismaService.menu.count({
      where,
    });
    const data = await this.prismaService.menu.findMany({
      where,
      skip: (page - 1) * size,
      take: size,
    });

    const treeData = buildTree(data);
    let fields: Prisma.MenuFieldRefs;
    if (dev) {
      fields = this.prismaService.menu.fields;
    }
    return {
      data: treeData,
      pager: {
        page,
        per_page: size,
        total,
      },
      ...(dev && {
        fields: Object.values(fields).map((field) => ({
          value: field.name,
          label: field.name,
        })),
      }),
    };
  }

  async get_menu(id: number) {
    const res = await this.prismaService.menu.findUnique({
      where: {
        id,
      },
    });
    return {
      data: res,
    };
  }

  async delete_menu(id: number) {
    const data = await this.prismaService.menu.findMany();

    function getChildrenId(id: number, arr: TreeItem[]) {
      const ids: number[] = [];
      function loopFn(id: number, arr: TreeItem[]) {
        ids.push(id);
        const children = data.filter((ele) => ele.parentId === id);
        if (children.length > 0) {
          children.forEach((ele) => loopFn(ele.id, arr));
        }
      }
      loopFn(id, arr);
      return ids;
    }
    const ids = getChildrenId(id, data);
    try {
      await this.prismaService.menu.deleteMany({
        where: {
          id: {
            in: ids,
          },
        },
      });
    } catch (error) {
      throw error;
    }
    return {
      data: ids,
      message: '菜单删除成功',
      messageType: 'success',
    };
  }
}
